/**
    Definitions of the channel descriptor data structures
    and common functionalities.
*/
#include "../Include/shm_common.h"
#include "../Include/channel.h"

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/shm.h>


/**
    Initializes a posix mutex
    @param mutex- the mutex
*/
void mutex_init( pthread_mutex_t *mutex )
{
	pthread_mutexattr_t attr;
	int pshared;


	if( pthread_mutexattr_init( &attr ) != 0 ) {
		fprintf( stderr,  "Error pthread_mutexattr_init(): %s\n", strerror(errno) );
	}
	if( pthread_mutexattr_setpshared( &attr, PTHREAD_PROCESS_SHARED ) != 0 ) {
		fprintf( stderr, "Error pthread_mutexattr_setpshared(): %s\n", strerror(errno) );
	}

	pthread_mutex_init( mutex, &attr );

	if( pthread_mutexattr_getpshared( &attr, &pshared) != 0 ) {
		fprintf( stderr, "Error pthread_mutexattr_getpshared(): %s\n", strerror(errno) );
	}
	if( pshared != PTHREAD_PROCESS_SHARED ) {
		fprintf( stderr, "Error, it's not shared... %d %d\n", pshared, PTHREAD_PROCESS_SHARED );
	}

	//pthread_mutexattr_destroy( &attr );
}

/**
    Initializes a posix condition variable
    @param cond - the condition variable
*/
void cond_init( pthread_cond_t *cond )
{
	pthread_condattr_t attr;
	int pshared;

	if( pthread_condattr_init( &attr ) != 0 ) {
		fprintf( stderr,"Error pthread_condattr_init(): %s\n", strerror(errno) );
	}
	if( pthread_condattr_setpshared( &attr, PTHREAD_PROCESS_SHARED ) != 0 ) {
		fprintf( stderr, "Error pthread_condattr_setpshared(): %s\n", strerror(errno) );
	}

	pthread_cond_init( cond, &attr );

	if( pthread_condattr_getpshared( &attr, &pshared) != 0 ) {
		fprintf( stderr, "Error pthread_condattr_getpshared(): %s\n", strerror(errno) );
	}
	if( pshared != PTHREAD_PROCESS_SHARED ) {
		fprintf( stderr, "Error, it's not shared... %d %d\n", pshared, PTHREAD_PROCESS_SHARED );
	}

	//pthread_condattr_destroy( &attr );
}

/**
    Lock of a channel
*/
inline void __LClockChannel( struct channel_t *ch ) {
	//return pthread_mutex_lock( & ch->mutex );
    spin_lock(& (ch->mutex));

}


/**
    Unlock of a channel
*/
inline void __LCunlockChannel( struct channel_t *ch ) {
	//return pthread_mutex_unlock( & ch->mutex );
    spin_unlock(&(ch->mutex));
}


/**
    Wait on a channel (or better on the associated condition variable)
*/
/*inline void __LCwaitOnChannel( struct channel_t *ch ) {
	//return pthread_cond_wait( & ch->cond, & ch->mutex );
	waitNotify(ch->cond, &(ch->mutex));
}
*/
/**
    Wake up a partner that is waiting on the channel (via condition variable)
*/
/*inline void __LCwakeUpChannel( struct channel_t *ch ) {
	//return pthread_cond_signal( & ch->cond );
    //notify(ch->cond);
}
*/
/**
    Set the key of an alternative command
*/
inline void __LCsetAltKey( struct channel_t *ch, key_t altKey )
{
	ch->altKey = altKey;
}
